package com.derbysoft.ota.application.translator.rq;

import java.util.List;

import javax.annotation.Nullable;

import org.apache.commons.collections.CollectionUtils;

import com.derbysoft.modules.eip.translator.Translator;
import com.derbysoft.ota.application.util.Dates;
import com.derbysoft.ota.interfaces.protocol._2009a.DateTimeSpanType;
import com.derbysoft.ota.interfaces.protocol._2009a.GuestCountType;
import com.derbysoft.ota.interfaces.protocol._2009a.RatePlanType;
import com.derbysoft.ota.interfaces.protocol._2009a.RoomTypeType;
import com.derbysoft.ota.interfaces.protocol._2009a.GuestCountType.GuestCount;
import com.derbysoft.ota.interfaces.protocol._2009a.RoomStaysType.RoomStay;
import com.derbysoft.remote.dswitch.generic.constants.AgeQualifyingType;
import com.derbysoft.remote.dswitch.hotel.dto.GuestCountDTO;
import com.derbysoft.remote.dswitch.hotel.dto.ReservationRoomStayDTO;
import com.derbysoft.remote.dswitch.hotel.dto.StayDateRangeDTO;
import com.google.common.base.Function;
import com.google.common.base.Preconditions;
import com.google.common.collect.Lists;
import com.googlecode.functionalcollections.FunctionalIterables;

public class RoomStayRQTranslator implements Translator<RoomStay, ReservationRoomStayDTO> {
	
	
	public ReservationRoomStayDTO translate(RoomStay source) {
		ReservationRoomStayDTO dest = new ReservationRoomStayDTO();

		Preconditions.checkArgument(source.getRatePlans() != null, "Rate plans required.");
		RatePlanType ratePlanType = source.getRatePlans().getRatePlan().iterator().next();
		dest.setRatePlanCode(ratePlanType.getRatePlanCode());
		dest.setRatePlanName(ratePlanType.getRatePlanName());

		Preconditions.checkArgument(source.getRoomTypes() != null, "Room types required.");
		RoomTypeType roomTypeType = source.getRoomTypes().getRoomType().iterator().next();
		dest.setRoomTypeCode(roomTypeType.getRoomTypeCode());
		dest.setRoomTypeName(roomTypeType.getRoomType());
		dest.setNumberOfUnits(roomTypeType.getNumberOfUnits().intValue());

		Preconditions.checkArgument(source.getTimeSpan() != null, "Time span required.");
		dest.setStayDateRange(stayDateRange(source.getTimeSpan()));

		Preconditions.checkArgument(source.getGuestCounts() != null, "Guest counts required.");
		dest.setGuestCounts(guest(source.getGuestCounts()));
		
		return dest;
	}

	private StayDateRangeDTO stayDateRange(DateTimeSpanType timeSpan) {
		return new StayDateRangeDTO(Dates.parse(timeSpan.getStart()), Dates.parse(timeSpan.getEnd()));
	}

	private List<GuestCountDTO> guest(GuestCountType guestCounts) {
		if (CollectionUtils.isNotEmpty(guestCounts.getGuestCount())) {
			return FunctionalIterables.make(guestCounts.getGuestCount()).map(
				new Function<GuestCount, GuestCountDTO>() {
					public GuestCountDTO apply(@Nullable GuestCount from) {
						return new GuestCountDTO(AgeQualifyingType.fromCode(Integer.valueOf(from.getAgeQualifyingCode())), from.getCount());
					}
			}).toList();
		}
		return Lists.newArrayList();
	}
}
